#include "outline/poly_bezier_builder_base.h"
#include "outline/outline.h"
#include <imglib/bitmap.h>
#include <imglib/winbmp.h>
#define WIN32_LEAN_AND_MEAN 
#include <windows.h>

#ifdef NDEBUG
#define VERIFY(x) x
#else
#define VERIFY(x) assert(x)
#endif

namespace outline {

template <typename R>
void render(controls<R> const & ctrls, img::bitmap & bmp)
{
	HDC hdc = CreateCompatibleDC(0);
	VERIFY (hdc);

	HBITMAP hbitmap = CreateCompatibleBitmap(hdc, bmp.width(), bmp.height());
	VERIFY (hbitmap);
	HGDIOBJ oldBmp = SelectObject(hdc, hbitmap);

	HBRUSH hbrush = CreateSolidBrush(RGB(0, 0, 0));
	RECT r = {0, 0, bmp.width(), bmp.height()};
	VERIFY (FillRect(hdc, &r, hbrush));
	VERIFY (DeleteObject(hbrush));

	//HPEN hpen = CreatePen(PS_SOLID, 1, RGB(255, 255, 255));
	//HGDIOBJ oldPen = SelectObject(hdc, hpen);
	hbrush = CreateSolidBrush(RGB(255, 255, 255));
	HGDIOBJ oldBrush = SelectObject(hdc, hbrush);

	VERIFY (BeginPath(hdc));

	unsigned n = ctrls.size();
	std::vector<POINT> pt(n);
	for (unsigned k = 0; k < n; ++k) {
		pt[k].x = ctrls[k].x;
		pt[k].y = ctrls[k].y;
	}
	VERIFY(PolyBezier(hdc, &pt[0], n));

	VERIFY (EndPath(hdc));
	// StrokeAndFillPath creates something dilated masks
	//          FillPath creates something eroded masks :(
	VERIFY (/*StrokeAnd*/FillPath(hdc));

	SelectObject(hdc, oldBrush);
	VERIFY (DeleteObject(hbrush));
	//SelectObject(hdc, oldPen);
	//VERIFY (DeleteObject(hpen));

	img::bitmap_info<img::bitmap> info;
	VERIFY (GetDIBits(hdc, hbitmap, 0, bmp.height(), bmp.data(), 
		ComposeBitmapInfo(info, bmp), DIB_RGB_COLORS));

	SelectObject(hdc, oldBmp);
	VERIFY (DeleteObject(hbitmap));
	VERIFY (DeleteDC(hdc));
}

template void render(controls<float> const & ctrls, img::bitmap & bmp);
template void render(controls<double> const & ctrls, img::bitmap & bmp);

} //namespace outline
